package com.sky.controller.admin;

import com.aliyuncs.http.HttpResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sky.dto.GoodsSalesDTO;
import com.sky.dto.TimeDTO;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.User;
import com.sky.result.Result;
import com.sky.service.IOrderDetailService;
import com.sky.service.IOrdersService;
import com.sky.service.IUserService;
import com.sky.service.IWorkspaceService;
import com.sky.vo.*;
import io.swagger.models.auth.In;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/admin/report")
public class ReportController {
    @Autowired
    private IOrdersService iOrdersService;
    @Autowired
    private IOrderDetailService iOrderDetailService;
    @Autowired
    private IUserService iUserService;
    @Autowired
    private IWorkspaceService iWorkspaceService;

    @GetMapping("/turnoverStatistics")
    public Result turnoverStatistics(TimeDTO timeDTO){

    //dateList  String  2022-10-01,2022-10-02,2022-10-03
        List<LocalDate> dateList = this.getListByDate(timeDTO);
        //营业额  和天数对应
        List<BigDecimal> turnoverList =new ArrayList<>();
        for (LocalDate date : dateList) {
            //去查找当天的总营业额
            LambdaQueryWrapper<Orders> qw =new LambdaQueryWrapper<>();
            LocalDateTime beginDate = LocalDateTime.of(date,LocalTime.MIN);
            LocalDateTime endDate = LocalDateTime.of(date,LocalTime.MAX);
            qw.between(Orders::getOrderTime,beginDate,endDate);
            qw.eq(Orders::getStatus,Orders.COMPLETED);
            //当天所有完成的订单列表
            List<Orders> list = iOrdersService.list(qw);
            //要注意如果一单没有会返回空，设置为0
            List<BigDecimal> amountList = list.stream()
                    .map(Orders::getAmount).collect(Collectors.toList());
            for (BigDecimal amount : amountList) {
                if (amount!=null){
                    turnoverList.add(amount);
                    continue;
                }turnoverList.add(BigDecimal.valueOf(0));
            }
        }

//        String join = String.join(",",list);
        //只能对于字符串类型的集合来处理
        //对于时间集合用 [推荐用]
        TurnoverReportVO vo= TurnoverReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .turnoverList(StringUtils.join(turnoverList,","))
                .build();
        //返回TurnoverReportVO
        return Result.success(vo);

    }

    @GetMapping("/userStatistics")
    public Result userStatistics(TimeDTO timeDTO){

        List<Long> newUserList =new ArrayList<>();
        List<Long> totalUserList =new ArrayList<>();

        List<LocalDate> dateList = this.getListByDate(timeDTO);
        for (LocalDate date : dateList) {
            LambdaQueryWrapper<User> qw =new LambdaQueryWrapper<>();
            LocalDateTime beginDate = LocalDateTime.of(date,LocalTime.MIN);
            LocalDateTime endDate = LocalDateTime.of(date,LocalTime.MAX);
            qw.lt(User::getCreateTime,endDate);
            long totalUser = iUserService.count(qw);
            totalUserList.add(totalUser);
            LambdaQueryWrapper<User> qw2 =new LambdaQueryWrapper<>();
            qw2.between(User::getCreateTime,beginDate,endDate);
            long newUser = iUserService.count(qw2);
            newUserList.add(newUser);
        }
        //每天用户总量
        //每天
        UserReportVO vo =UserReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .totalUserList(StringUtils.join(totalUserList,","))
                .newUserList(StringUtils.join(newUserList,","))
                .build();
        return Result.success(vo);

    }



    @GetMapping("/ordersStatistics")
    public Result ordersStatistics(TimeDTO timeDTO){
        List<LocalDate> dateList = this.getListByDate(timeDTO);

        Long orderCountAll =0L;
        Long validOrderCountAll =0L;
        //每日订单数
        List<Long> orderCountList =new ArrayList<>();
        List<Long> validOrderCountList=new ArrayList<>();
        for (LocalDate date : dateList) {
            LambdaQueryWrapper<Orders> qw =new LambdaQueryWrapper<>();
            LocalDateTime beginDate = LocalDateTime.of(date,LocalTime.MIN);
            LocalDateTime endDate = LocalDateTime.of(date,LocalTime.MAX);
            qw.between(Orders::getOrderTime,beginDate,endDate);
            long orderCount = iOrdersService.count(qw);
            orderCountAll+=orderCount;
            orderCountList.add(orderCount);
            qw.eq(Orders::getStatus,Orders.COMPLETED);
            //每日有效订单
            long validOrderCount = iOrdersService.count(qw);
            validOrderCountAll+=validOrderCount;
            validOrderCountList.add(validOrderCount);
            //
        }
        double validCS = Double.parseDouble(validOrderCountAll+"") ;
        double orderCS = Double.parseDouble(orderCountAll + "");
        Double orderCompletionRate =0.0;
        if(orderCS!=0) {
            orderCompletionRate= validCS / orderCS;
        }

        //返回一个OrderReportVo
        OrderReportVO vo =OrderReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .orderCountList(StringUtils.join(orderCountList,","))
                .validOrderCountList(StringUtils.join(validOrderCountList,","))
                .totalOrderCount(Math.toIntExact(orderCountAll))
                .validOrderCount(Math.toIntExact(validOrderCountAll))
                .orderCompletionRate(orderCompletionRate)
                .build();
        return Result.success(vo);
    }


    @GetMapping("/top10")
    public Result top10(TimeDTO timeDTO){
        LambdaQueryWrapper<Orders> lqw =new LambdaQueryWrapper<>();
        lqw.between(Orders::getOrderTime,timeDTO.getBegin(),timeDTO.getEnd());
        lqw.eq(Orders::getStatus,Orders.COMPLETED);
        //符合时间的订单集合
        List<Long> vOrderIdList = iOrdersService.list(lqw)
                .stream().map(Orders::getId).collect(Collectors.toList());
            //根据这些订单找出最多
            //根据名字分组查询，找出名字和数量

        //select name ,orderId, number
        //将name相同的菜品的number添加在一起
        LambdaQueryWrapper <OrderDetail> qw =new LambdaQueryWrapper<>();
        qw.select(OrderDetail::getName,OrderDetail::getNumber);
        qw.in(OrderDetail::getOrderId,vOrderIdList);
        //符合要求的订单详情列表
        List<OrderDetail> list = iOrderDetailService.list(qw);
        //根据name相同的订单合并为一个，并且number相加

        Map<String, List<OrderDetail>> map = list.stream().collect(Collectors.groupingBy(OrderDetail::getName));
        List<GoodsSalesDTO> collect = map.entrySet().stream().map(s -> {
            String name = s.getKey();
            int sum = s.getValue().stream().mapToInt(OrderDetail::getNumber).sum();
            return new GoodsSalesDTO(name, sum);
        }).collect(Collectors.toList());
        //todo:待再次分析 Stream流的使用
        //获取排序后的集合
        List<GoodsSalesDTO> details = collect.stream().
                sorted(Comparator.comparing(GoodsSalesDTO::getNumber).reversed()).collect(Collectors.toList());
        List<String> nameList = details.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        List<Integer> numList = details.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());


        //返回一个SalesTop10ReportVO
        SalesTop10ReportVO vo =SalesTop10ReportVO.builder()
                .nameList(StringUtils.join(nameList,","))
                .numberList(StringUtils.join(numList,","))
                .build();
        return Result.success(vo);

    }

    /**
     * 获取时间String
     * @param dto
     * @return
     */
    private List<LocalDate> getListByDate(TimeDTO dto){
        LocalDate begin = dto.getBegin();
        LocalDate end = dto.getEnd();
        //从begin到end的日期集合
        //时间虽然不能比大小，但是可以比较是否相等
        //所以不用时间戳来计算时间·
        List<LocalDate> dateList =new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)){
            begin= begin.plusDays(1);
            dateList.add(begin);
        }
        return dateList;
    }

    /**
     * 导出运营数据报表
     * @param response
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response){
        //查库
        LocalDate  dateBegin = LocalDate.now().minusDays(30);
        LocalDate  dateEnd = LocalDate.now().minusDays(1);
        LocalDateTime begin = LocalDateTime.of(dateBegin, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(dateEnd, LocalTime.MAX);
        BusinessDataVO businessDataVO = iWorkspaceService.getBusinessData(begin, end);
        //通过POI写入Excel
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            XSSFWorkbook excel =new XSSFWorkbook(in);

            //填充数据--时间[注意大小写]30天的
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue("时间："+dateBegin+"至"+dateEnd);
            //填充数据获得第四行
            XSSFRow row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());
            row= sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());


            //明细数据每天的
            for (int i = 0; i < 30; i++) {
                LocalDate date = dateBegin.plusDays(i);
                BusinessDataVO businessData = iWorkspaceService.getBusinessData
                        (LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
                row = sheet.getRow(i + 7);
                row.getCell(1).setCellValue(date.toString());
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());
            }

            //通过输出流 将文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            out.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
